/****************************************************
 * 若依-vue 路由权限模块（已修复 name 冲突）
 * 复制即可使用
 ***************************************************/
import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'

const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: []
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes
    }
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise(resolve => {
        getRouters().then(res => {
          const sdata = JSON.parse(JSON.stringify(res.data))
          const rdata = JSON.parse(JSON.stringify(res.data))

          /* ① 先转组件 */
          const sidebarRoutes = filterAsyncRouter(sdata)
          const rewriteRoutes = filterAsyncRouter(rdata, false, true)

          /* ② 再加前缀防重名 */
          processName('', sidebarRoutes)
          processName('', rewriteRoutes)

          /* ③ 后续原有逻辑不动 */
          const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
          rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
          router.addRoutes(asyncRoutes)
          commit('SET_ROUTES', rewriteRoutes)
          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          commit('SET_TOPBAR_ROUTES', sidebarRoutes)
          resolve(rewriteRoutes)
        })
      })
    }
  }
}

/*************** 工具函数 ****************/

/* 1. 递归加前缀，防止 name 冲突 */
function processName(parentName, routes) {
  routes.forEach(rt => {
    const raw = rt.name || rt.path.split('/').pop() || 'Index'
    const full = parentName ? `${parentName}.${raw}` : raw
    rt.name = full.charAt(0).toUpperCase() + full.slice(1)

    if (rt.children && rt.children.length) processName(rt.name, rt.children)
  })
}

/* 2. 转换异步路由组件 */
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter(route => {
    if (type && route.children) route.children = filterChildren(route.children)

    if (route.component) {
      if (route.component === 'Layout') route.component = Layout
      else if (route.component === 'ParentView') route.component = ParentView
      else if (route.component === 'InnerLink') route.component = InnerLink
      else route.component = loadView(route.component)
    }

    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route.children
      delete route.redirect
    }
    return true
  })
}

function filterChildren(childrenMap, lastRouter = false) {
  const children = []
  childrenMap.forEach(el => {
    el.path = lastRouter ? `${lastRouter.path}/${el.path}` : el.path
    if (el.children && el.children.length && el.component === 'ParentView') {
      children.push(...filterChildren(el.children, el))
    } else children.push(el)
  })
  return children
}

/* 3. 权限过滤 */
export function filterDynamicRoutes(routes) {
  return routes.filter(route => {
    if (route.permissions) return auth.hasPermiOr(route.permissions)
    if (route.roles) return auth.hasRoleOr(route.roles)
    return true
  })
}

/* 4. 懒加载 */
export const loadView = view =>
  process.env.NODE_ENV === 'development'
    ? resolve => require([`@/views/${view}`], resolve)
    : () => import(`@/views/${view}`)

export default permission
